<?php

/**
 * Session utilisateur
 *
 * @package cass
 * @author Mickaël CASTANHEIRO <mickael.castanheiro@gmail.com>
 * @version 1.0
 */

namespace cass;

class Session extends Singleton {

    protected $user;

    /**
     * Construit l'objet session
     * Vérifie la _SESSION et les _COOKIES
     */
    protected function __construct() {
        $save = false;
        if (!empty($_SESSION['user_id']) AND !empty($_SESSION['user_key'])) {
            $user_id = $_SESSION['user_id'];
            $user_key = $_SESSION['user_key'];
        } elseif (!empty($_COOKIE['user_id']) AND !empty($_COOKIE['user_key'])) {
            $user_id = $_COOKIE['user_id'];
            $user_key = $_COOKIE['user_key'];
            $save = true;
        }

        // Trouve le User correspondant
        if (!empty($user_id) AND !empty($user_key)) {
            $user = Doctrine::getInstance()->find('User', $user_id);
            // S'il y a un résultat et que le mot de passe est bon
            if (!empty($user) AND ($user->getPassword() == $user_key)) {
                $this->connect($user, $save);
            }
        }
    }

    /**
     * Connecte la session avec un objet User
     * @param <type> $_user User de la session
     */
    public function connect($_user, $_cookie = false) {
        $this->user = $_user;
        $this->saveSession();
        if ($_cookie)
            $this->saveCookie();
    }

    /**
     * Déconnecte l'utilisateur
     */
    public function unconnect() {
        $maxTime = $_SERVER['REQUEST_TIME'] - 10000; // Expiration bien avant aujourd'hui

        unset($this->user);
        unset($_SESSION);
        session_destroy();
        setcookie('user_id', '', $maxTime, '/');
        setcookie('user_key', '', $maxTime, '/');
    }

    /**
     * Sauvegarde l'id/key dans la session
     */
    public function saveSession() {
        if (empty($this->user)) {
            return false;
        }
        $_SESSION['user_id'] = $this->user->getId();
        $_SESSION['user_key'] = $this->user->getPassword();
    }

    /**
     * Sauvegarde l'id/key dans la session
     */
    public function saveCookie() {
        if (!$this->isAuthenticated()) {
            return false;
        }
        $maxTime = $_SERVER['REQUEST_TIME'] + 2592000; // 2592000 = 30jours
        setcookie('user_id', $this->user->getId(), $maxTime, '/');
        setcookie('user_key', $this->user->getPassword(), $maxTime, '/');
    }

    /**
     * Indique si l'utilisateur est connecté
     * @return <boolean> Utilisateur connecté
     */
    public function isAuthenticated() {
        return (!empty($this->user) );
    }

    /**
     * Indique si l'utilisateur a un droit spécial
     * @param <string> $_name Nom du droit
     * @return <boolean> A le droit ?
     */
    public function hasCredential($_name) {
        if (!$this->isAuthenticated()) {
            return false;
        }

        foreach ($this->user->getCredentials() AS $credential) {
            if ($credential->getName() == $_name) {
                return true;
            }
        }
        return false;
    }

    /**
     * Indique si l'utilisateur a l'un des droits
     * @param <string> (multi) $_name Nom des droits
     * @return <boolean> A l'un des droit ?
     */
    public function hasOneOfCredentials() {
        if (!$this->isAuthenticated()) {
            return false;
        }

        $_names = func_get_args();
        foreach ($this->user->getCredentials() AS $credential) {
            if (in_array($credential->getName(), $_names)) {
                return true;
            }
        }
        return false;
    }

    /**
     * Indique si l'utilisateur a tous les droits demandés
     * @param <string> (multi) $_name Nom des droits
     * @return <boolean> A tous les droits ?
     */
    public function hasAllOfCredentials() {
        if (!$this->isAuthenticated()) {
            return false;
        }

        $_names = func_get_args();
        foreach ($this->user->getCredentials() AS $credential) {
            $key = array_search($credential->getName(), $_names);
            if ($key !== false) {
                unset($_names[$key]); // On enlève des droits à trouver celui qui est trouvé
            }

            if (empty($_names)) {
                return true; // Si aucun droit reste à trouver, c'est qu'on les a tous
            }
        }
        return false;
    }

}
